/**
 * style attribute 对比
 * @param {CSSStyleDeclaration} current
 * @param {CSSStyleDeclaration} target
 * @returns {Boolean}
 */
export function styleEqual(current, target) {
    if (current.length === target.length) {
        const set = new Set([...current, ...target])
        if (target.length === set.size) {
            return Array.from(target).every(attr => {
                return current[attr] === target[attr]
            })
        }
    }
    return false
}

export function isTextNode(node) {
    return node instanceof Node && node.nodeType === 3
}

export function invalidTextNode(root) {
    const invalid = /^\n\s+$/
    const iterator = document.createNodeIterator(root, 4, {
        acceptNode(node) {
            if (invalid.test(node.data) && !isTextNode(node.previousSibling) && !isTextNode(node.nextSibling)) {
                return NodeFilter.FILTER_ACCEPT
            }
        },
    })
    const nodes = []
    while (iterator.nextNode()) {
        nodes.push(iterator.referenceNode)
    }
    return nodes
}

/**
 * 移除无效的 TextNode
 * @param {Element} root 跟节点
 */
export function removeInvalidTextNode(root) {
    const invalid = /^\n\s+/
    const iterator = document.createNodeIterator(root, 4, {
        acceptNode(node) {
            if (invalid.test(node.data) && !isTextNode(node.previousSibling) && !isTextNode(node.nextSibling)) {
                return NodeFilter.FILTER_ACCEPT
            }
        },
    })
    while (iterator.nextNode()) {
        iterator.referenceNode.remove()
    }
}

/**
 * 数据类型原型
 */
export function type(tar) {
    return Object.prototype.toString
        .call(tar)
        .toLowerCase()
        .replace(/(\[\w+\s+|\])/g, '')
}

/**
 * 从 style 标签中获取符合条件的 CSSRule 对象
 * @param {HTMLStyleElement} style style标签
 * @param {String} selectorText css选择器
 * @returns {CSSRule}
 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/CSSStyleSheet
 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/CSSRule
 */
export function styleCssRule(style, selectorText) {
    const rules = style.sheet.cssRules
    let rule = Array.prototype.find.call(rules, e => e.selectorText === selectorText)
    if (!rule) {
        style.sheet.insertRule(`${selectorText} {}`, rules.length)
        rule = rules[rules.length - 1]
    }
    return rule
}

export function eachArray(data, fn) {
    Array.from(data).forEach(fn)
}

export function eachObject(data, fn) {
    Object.entries(data).forEach(([k, v]) => fn(k, v))
}